type RequestOptions = {
    timeout?: number,
} & RequestInit;

export type JsonResp<T> = {
    code: number,
    data: T,
    msg: string,
}

function setTimeoutReject(options: RequestOptions, timeout: number, reject: Function) {
    const requestTimeout = options.timeout || timeout;
    const controller = new AbortController();
    options.signal = options.signal || controller.signal;
    setTimeout(() => {
        controller.abort();
        reject(new Error('Request timeout'));
    }, requestTimeout);
}

export const createRequest = (timeout: number) => {
    return (url: string, options = {}): Promise<Response> => {
        options = {
            mode: "cors",
            credentials: "include",
            headers: {
                "Content-Type": "application/json",
                'Access-Control-Allow-Origin': '*',
            },
            ...options
        };
        return new Promise((resolve, reject) => {
            setTimeoutReject(options, timeout, reject);
            if (url.startsWith('/')) {
                url = url.substring(1);
            }
            const realUrl = url.includes('http') ? url : `${window.location.origin}/${url}`;
            fetch(realUrl, options).then(resolve, reject);
        });
    }
}
export const doJsonRequest = async (url: string, options?: RequestOptions): Promise<JsonResp<any>> => {
    return createRequest(3000)(url, options)
        .then(response => response.json());
};
export const doGetRequest = function (url: string, params?: any, timeout = 3000) {
    let target = url;
    if (params) {
        // 拼接参数
        target = Object.entries(params).reduce((pre, [key, value]) => {
            return `${pre + key}=${value}&`;
        }, url + "?")
    }
    return createRequest(timeout)(target, {
        timeout
    })
        .then(response => response.json());
}
export const doPostRequest = function (url: string, params?: any, timeout = 3000) {
    return createRequest(timeout)(url, {
        timeout,
        body: JSON.stringify(params),
        method: "POST"
    }).then(response => response.json());
}

export const doSubmitForm = function (url: string, formData: any, timeout = 3000) {
    return createRequest(timeout)(url, {
        timeout,
        body: formData,
        method: "POST",
        headers: {
            'Access-Control-Allow-Origin': '*',
        },
    }).then(response => response.json());
}

